#pragma once

#include <SFML/Graphics.hpp>
#include <vector>
#include <memory>


struct job;
struct peon;


enum pathable : char
{
    PATHABLE,
    NON_PATHABLE
};

struct vec2
{
    int x, y;
};

bool operator== (const vec2& lhs, const vec2& rhs);

struct block
{
    block* b;

    int art_num = 0;
    int x, y;

    int type_id = -1;

    void push();
    void pull();

    void tick();

    void init(int);

    void notify_job_done(int trait);
    void notify_job_doing(int trait);
    void notify_job_stopped(int trait);

    std::vector<float> trait_nums;
    std::vector<bool> jobs_going;
    std::vector<bool> jobs_doing;
    std::vector<std::shared_ptr<job>> jobs;

    std::pair<int, int> find_nearest_free_space();

    int pskip = 0;
};

struct job
{
    ///remote job after push
    //std::shared_ptr<job> remote = NULL;

    ///where do i job
    int x, y;
    ///thing to interact with
    block* b = NULL;

    peon* p = NULL;
    ///how much do i need to job
    float priority;

    int ticks_to_complete = 1;

    std::shared_ptr<job> push();
    void cancel();

    job();

    job(int, int, float, block*, int, int, int);

    ///id of the block trait this uses
    int block_trait_id = -1;
    ///id of the peon trait this uses
    int peon_trait_id = -1;
};

struct peon
{
    float x, y;
    int oex = -1, oey = -1;
    peon* p;

    bool job_assigned = false;
    std::shared_ptr<job> task;

    std::vector<bool> needs;

    void push();
    void pull();

    void job_process();

    sf::Color col;

    std::vector<vec2> pth;

    unsigned int pstate = -1;

    unsigned int mn = 0;

    bool needy = false;

    static std::vector<std::string> trait_list;

    std::vector<std::pair<std::string, float>> traits = {{"damage", 0.0f}, {"hunger", 0.0f}, {"fatigue", 0.0f}};

    void path();
    void move(float ftime);
    void tick();
    void job_cancel();

    bool should_accept(std::shared_ptr<job>);

    peon();
};

struct square
{
    int ax, ay, bx, by;
    sf::Color col;
    pathable is_pathable = PATHABLE;

    void push();
};

struct projectile
{
    int x, y;
    int sx, sy;
    sf::Color col;
};

bool operator<(const job& j1, const job& j2);
bool o_more(std::shared_ptr<job> j1, std::shared_ptr<job> j2);
